﻿#ifndef COMMAND_H
#define COMMAND_H
#include <QObject>
#include <QMutexLocker>
#include <QMutex>
#include <iostream>
#include "rapidjson/AIGCJson.hpp"
#include "./Model/Dto/ArchiveRegisterRequest.h"
using namespace std;
using namespace aigc;

enum ArvLevel
{
    FirstLevel, //一级档案
    SecondLevel,    //二级档案
    ThirdLevel  //三级档案
};

enum StorgeGoodsState
{
    State_Free = 1,
    State_Occupy
};

enum CmdState
{
    CmdState_Ready,    //就绪态，已分配好出货口，只要前一个指令执行完成即可执行此指令
    CmdState_Running,  //执行态，正在执行的指令
    CmdState_Blocked,  //阻塞态，无货位或者无出货口导致命令阻塞，等待货位或出货口空闲
    CmdState_Suspended,    //挂起态
    CmdState_dead,  //死亡态，命令有问题无法执行
    CmdState_Done   //完成态，指令正常成功完成
};

enum PortGoodsState
{
    None,   //无指令，无物理占据货位
    PhysicalOccupy = 0x01,  //物理占据货位
    CmdOccupy = 0x02,   //命令占据货位
    CmdOutCab = 0x04    //出柜指令
};

enum UserState
{
    normal,
    locked
};

enum UserRole
{
    Superadmin = -1,
    admin = 0,
    Ordinaryuser = 1
};

//出货口货位状态指示类
class PortGoodsIndicator
{
private:
    //第1位-物理占据位 0-无物理档案  1-有物理档案
    //第2位-命令占据位 0-无命令分配  1-有命令分配
    //第3位-命令类型位 0-入柜指令  1-出柜指令
    uint8_t state = 0x00;
    QString qrcode;
public:
    int standard = 0;
    void setPhysicalOccupy(bool bl)
    {
        if(bl)
            state = state | PhysicalOccupy;
        else
            state = state & (~PhysicalOccupy);
    }

    void setCmdOccupy(bool bl)
    {
        if(bl)
            state = state | CmdOccupy;
        else
        {
            state = state & (~CmdOccupy);
            state = state & (~CmdOutCab);
        }
    }

    void setCmdOutCab(bool bl)
    {
        if(bl)
            state = state | CmdOutCab;
        else
            state = state & (~CmdOutCab);
    }

    void clearOccupy()
    {
        state = 0x00;
    }

    bool getOccupy()
    {
        if((state & PhysicalOccupy) || (state & CmdOccupy))
            return true;
        else
            return false;
    }

    uint8_t getState()
    {
        return  state;
    }

    bool isOutCab()
    {
        return state & CmdOutCab;
    }

    bool isCmdOcuupy()
    {
        return state & CmdOccupy;
    }
};

//上位机下发给屏的出入柜指令
class InOutCabCommand_Server
{
public:
    QString CmdType;    //指令类型
    int DeviceNo;   //柜号
    int LayerNo=-1;    //层号
    int CellNo=-1;     //格号
    QString Face;     //AB面
    int PortNo=-1;     //出货口编号
    int Standard;   //规格
    CmdState CmdState = CmdState_Blocked;   //指令状态
    QString Name;   //档案名称
    QString CardID; //档案编号
    QString QRCode; //二维码

    bool operator==(const InOutCabCommand_Server& other) const {
        if(QRCode == other.QRCode)
        {
            return true;
        }
        else
            return false;
    }

};
enum ARVCMDTYPE{
    type_incab,
    type_outcab
};

enum ARVCMDFACE{
    face_a,
    face_b
};
//屏下发给Linux控制板的出入柜指令
class InOutCabCommand_Board
{
public:
    int32_t PortLocation_X; //出货口X
    int32_t PortLocation_Y; //出货口Y
    int32_t StorgeLocation_X;   //货位X
    int32_t StorgeLocation_Y;   //货位Y
    uint8_t Type; //true-存 false-取
    uint8_t Face; //货位在A面还是B面  true-A  false-B
    bool HaveNext;  //是否有下一条指令
    bool isExCompleted = true;  //动作是否完成
    int8_t StepCnt; //调试状态下步骤状态
    bool isDebug;   //是否分步调试指令
    QString QRCode; //二维码
    QString CmdCode;

    // 重载 == 运算符 判断两条指令的内容是否相同
    bool operator==(const InOutCabCommand_Board& other) const {
        if(PortLocation_X == other.PortLocation_X &&
                PortLocation_Y == other.PortLocation_Y &&
                StorgeLocation_X == other.StorgeLocation_X &&
                StorgeLocation_Y == other.StorgeLocation_Y &&
                Type == other.Type &&
                Face == other.Face &&
                QRCode == other.QRCode &&
                isDebug == other.isDebug)
            return true;
        else
            return  false;
    }
};

class InOutCabCommandResponse
{
public:
    string CmdType;
    string QRCode;
    bool Result;
    int ErrCode;
    string ErrMsg;
    AIGC_JSON_HELPER(CmdType, QRCode, Result,ErrCode,ErrMsg);
};

class QRLocateCommand
{
public:
    int totalLayer; //总层数
    int totalSub;   //总节数
    int portLayer;  //出货口所在层
    QList<int> subWidth;
    bool isExCompleted = true;  //动作是否完成
    int8_t StepCnt; //调试状态下步骤状态
    bool isDebug;   //是否分步调试指令

    // 重载 == 运算符 判断两条指令的内容是否相同
    bool operator==(const QRLocateCommand& other) const {
        if(totalLayer == other.totalLayer &&
                totalSub == other.totalSub &&
                portLayer == other.portLayer &&
                isDebug == other.isDebug)
            return true;
        else
            return  false;
    }
};

class QRLocateCommandResponse
{
public:
    bool LocateResult;
    string LocateType;
    int LocateCnt;
    int LocatePosition;

    AIGC_JSON_HELPER(LocateResult, LocateType, LocateCnt,LocatePosition);
};

class SearchCmdModel:public InOutCabCommand_Server,public ArchiveRegisterRequest
{

};

//Q_DECLARE_METATYPE(InOutCabCommand_Board)
//Q_DECLARE_METATYPE(InOutCabCommand_Server)
//Q_DECLARE_METATYPE(QRLocateCommand)
#endif // COMMAND_H
